package cn.pku.edu.cs.ldn.thread;

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import cn.pku.edu.cs.ldn.util.FileUtil;
import android.util.Log;

public class HttpDownloadThread extends ObservableThread {
	private static final String TAG = "HttpDownloadThread";
	private static final boolean DEBUG = true;

	public static final String MIME_IMAGE_PNG = "image/png";
	public static final String MIME_IMAGE_GIF = "image/gif";
	public static final String MIME_IMAGE_JPG = "image/jpeg";

	protected boolean requestStop = false;

	protected String remotePath = null;
	protected String localPath = null;
	protected String contentType = null;

	public HttpDownloadThread(String url, String path,
			ThreadObserverHandler handler) {
		remotePath = url;
		localPath = path;
		addObserver(handler);
	}

	public void setContentType(String mimeType) {
		contentType = mimeType;
	}

	@Override
	public boolean requestStop() {
		requestStop = true;
		return true;
	}

	@Override
	public void run() {
		if (requestStop == false) {
			download();
		}
		notifyFinish(null);
	}

	@Override
	public synchronized void start() {
		if (isReadyToStart()) {
			super.start();
		} else {
			if (DEBUG)
				Log.e(TAG, "start: NOT ready, refuse to start");
		}
	}

	private boolean isReadyToStart() {
		if (remotePath == null || localPath == null) {
			if (DEBUG)
				Log.e(TAG, "isReadyToStart: illegal remote or local path");
			return false;
		}
		return true;
	}

	protected boolean download() {
		HttpURLConnection httpURLConnection = null;
		InputStream inputStream = null;
		FileOutputStream fileOutputStream = null;
		boolean complete = false;

		try {
			fileOutputStream = new FileOutputStream(localPath);
			URL url = new URL(remotePath);
			httpURLConnection = (HttpURLConnection) url.openConnection();
			inputStream = new BufferedInputStream(
					httpURLConnection.getInputStream());

			byte[] buffer = new byte[1024];
			int bufferRead = 0;
			int bufferReadSum = 0;
			int length = httpURLConnection.getContentLength();
			while (requestStop == false) {
				bufferRead = inputStream.read(buffer, 0, buffer.length);
				if (requestStop)
					break;
				if (bufferRead >= 0) {
					bufferReadSum += bufferRead;
					fileOutputStream.write(buffer, 0, bufferRead);
					if (DEBUG)
						Log.v(TAG, "download: " + bufferReadSum + " / "
								+ length);
				} else {
					if (DEBUG)
						Log.v(TAG,
								"download: end of input stream has been reached");
					complete = true;
					break;
				}
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (httpURLConnection != null) {
			httpURLConnection.disconnect();
		}
		try {
			if (inputStream != null) {
				inputStream.close();
			}
			if (fileOutputStream != null) {
				fileOutputStream.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (complete == false) {
			if (DEBUG)
				Log.v(TAG, "download: deleting unfinished file");
			FileUtil.deleteFile(localPath);
			return false;
		} else {
			if (DEBUG)
				Log.v(TAG, "download: success!");
			return true;
		}
	}
}
